﻿using Atomic;
using JT808.Protocol;
using JTActiveSafety.Gateway.Configurations;
using JTActiveSafety.Gateway.Internal;
using JTActiveSafety.Gateway.Services;
using JTActiveSafety.Gateway.Sessions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.IO.Pipelines;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;

namespace JTActiveSafety.Gateway
{
    public class JTActiveSafetyTcpServer : IHostedService
    {
        private readonly IKestrelTrace _trace;
        private readonly ILogger _serverLogger;
        private readonly ILogger _lifetimeLogger;
        private readonly IServer _server;
        private readonly SocketTransportOptions _options;

        public JTActiveSafetyTcpServer(
            ILoggerFactory loggerFactory,
            IServer server,
            SocketTransportOptions options)
        {
            _serverLogger = loggerFactory.CreateLogger("JTActiveSafety.Hosting.Server");
            _lifetimeLogger = loggerFactory.CreateLogger("JTActiveSafety.Lifetime");
            _trace = new KestrelTrace(_serverLogger);
            _server = server;
            _options = options;
        }

        #region IHostedService
        /// <summary>
        /// 
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            _serverLogger.LogInformation("JTActiveSafety Tcp Server Start");
            ConnectionDelegate connectionDelegate = OnMessageHandler;
            await _server.StartAsync(connectionDelegate, cancellationToken);
        }


        private Task OnMessageHandler(ConnectionContext connection)
        {
            return Task.Factory.StartNew(() =>
            {
                _serverLogger.LogInformation($"正在处理：{connection.RemoteEndPoint}");
                new JTActiveSafetyMessageHandler(connection, _options.MemoryPoolFactory(), _trace).Execute();
            });
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task StopAsync(CancellationToken cancellationToken)
        {
            _serverLogger.LogInformation("JTActiveSafety Tcp Server Stop");

            try
            {
                await _server.StopAsync(cancellationToken);
            }
            finally
            {
                //HostingEventSource.Log.HostStop();
            }
        }
        #endregion
    }
}